<?php
/**
 * PortfolioBudget
 *
 * PHP version 5
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 */

/**
 * Amazon Ads API - Portfolios
 *
 * Portfolios consist of campaigns that are grouped together and linked to a distinct Advertiser Account. The term 'advertiser' refers to a brand, entity, account identifier, or claim identifier. Multiple portfolios are supported within an Advertiser Account.
 *
 * OpenAPI spec version: 2.0
 * 
 * Generated by:https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api.git
 * AmazonAdvertisingApi Codegen version: 3.0.51
 */
/**
 * NOTE: This class is auto generated by the AmazonAdvertisingApi code generator program.
 *https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 * Do not edit the class manually.
 */

namespace AmazonAdvertisingApi\Model;

use \ArrayAccess;
use \AmazonAdvertisingApi\ObjectSerializer;

/**
 * PortfolioBudget Class Doc Comment
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 */
class PortfolioBudget implements ModelInterface, ArrayAccess
{
    const DISCRIMINATOR = null;

    /**
      * The original name of the model.
      *
      * @var string
      */
    protected static $AmazonAdvertisingApiModelName = 'Portfolio_budget';

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $AmazonAdvertisingApiTypes = [
        'amount' => 'float',
        'currency_code' => 'string',
        'policy' => 'string',
        'start_date' => 'string',
        'end_date' => 'string'
    ];

    /**
      * Array of property to format mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $AmazonAdvertisingApiFormats = [
        'amount' => null,
        'currency_code' => null,
        'policy' => null,
        'start_date' => null,
        'end_date' => null
    ];

    /**
     * Array of property to type mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function AmazonAdvertisingApiTypes()
    {
        return self::$AmazonAdvertisingApiTypes;
    }

    /**
     * Array of property to format mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function AmazonAdvertisingApiFormats()
    {
        return self::$AmazonAdvertisingApiFormats;
    }

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @var string[]
     */
    protected static $attributeMap = [
        'amount' => 'amount',
        'currency_code' => 'currencyCode',
        'policy' => 'policy',
        'start_date' => 'startDate',
        'end_date' => 'endDate'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'amount' => 'setAmount',
        'currency_code' => 'setCurrencyCode',
        'policy' => 'setPolicy',
        'start_date' => 'setStartDate',
        'end_date' => 'setEndDate'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'amount' => 'getAmount',
        'currency_code' => 'getCurrencyCode',
        'policy' => 'getPolicy',
        'start_date' => 'getStartDate',
        'end_date' => 'getEndDate'
    ];

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @return array
     */
    public static function attributeMap()
    {
        return self::$attributeMap;
    }

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @return array
     */
    public static function setters()
    {
        return self::$setters;
    }

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @return array
     */
    public static function getters()
    {
        return self::$getters;
    }

    /**
     * The original name of the model.
     *
     * @return string
     */
    public function getModelName()
    {
        return self::$AmazonAdvertisingApiModelName;
    }

    const CURRENCY_CODE_USD = 'USD';
    const CURRENCY_CODE_CAD = 'CAD';
    const CURRENCY_CODE_MXN = 'MXN';
    const CURRENCY_CODE_BRL = 'BRL';
    const CURRENCY_CODE_GBP = 'GBP';
    const CURRENCY_CODE_JPY = 'JPY';
    const CURRENCY_CODE_EUR = 'EUR';
    const CURRENCY_CODE_AUD = 'AUD';
    const CURRENCY_CODE_AED = 'AED';
    const CURRENCY_CODE_SEK = 'SEK';
    const CURRENCY_CODE_PLN = 'PLN';
    const CURRENCY_CODE_SGD = 'SGD';
    const CURRENCY_CODE__TRY = 'TRY';
    const POLICY_DATE_RANGE = 'dateRange';
    const POLICY_MONTHLY_RECURRING = 'monthlyRecurring';

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getCurrencyCodeAllowableValues()
    {
        return [
            self::CURRENCY_CODE_USD,
            self::CURRENCY_CODE_CAD,
            self::CURRENCY_CODE_MXN,
            self::CURRENCY_CODE_BRL,
            self::CURRENCY_CODE_GBP,
            self::CURRENCY_CODE_JPY,
            self::CURRENCY_CODE_EUR,
            self::CURRENCY_CODE_AUD,
            self::CURRENCY_CODE_AED,
            self::CURRENCY_CODE_SEK,
            self::CURRENCY_CODE_PLN,
            self::CURRENCY_CODE_SGD,
            self::CURRENCY_CODE__TRY,
        ];
    }
    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getPolicyAllowableValues()
    {
        return [
            self::POLICY_DATE_RANGE,
            self::POLICY_MONTHLY_RECURRING,
        ];
    }

    /**
     * Associative array for storing property values
     *
     * @var mixed[]
     */
    protected $container = [];

    /**
     * Constructor
     *
     * @param mixed[] $data Associated array of property values
     *                      initializing the model
     */
    public function __construct(array $data = null)
    {
        $this->container['amount'] = isset($data['amount']) ? $data['amount'] : null;
        $this->container['currency_code'] = isset($data['currency_code']) ? $data['currency_code'] : null;
        $this->container['policy'] = isset($data['policy']) ? $data['policy'] : null;
        $this->container['start_date'] = isset($data['start_date']) ? $data['start_date'] : null;
        $this->container['end_date'] = isset($data['end_date']) ? $data['end_date'] : null;
    }

    /**
     * Show all the invalid properties with reasons.
     *
     * @return array invalid properties with reasons
     */
    public function listInvalidProperties()
    {
        $invalidProperties = [];

        $allowedValues = $this->getCurrencyCodeAllowableValues();
        if (!is_null($this->container['currency_code']) && !in_array($this->container['currency_code'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value for 'currency_code', must be one of '%s'",
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getPolicyAllowableValues();
        if (!is_null($this->container['policy']) && !in_array($this->container['policy'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value for 'policy', must be one of '%s'",
                implode("', '", $allowedValues)
            );
        }

        return $invalidProperties;
    }

    /**
     * Validate all the properties in the model
     * return true if all passed
     *
     * @return bool True if all properties are valid
     */
    public function valid()
    {
        return count($this->listInvalidProperties()) === 0;
    }


    /**
     * Gets amount
     *
     * @return float
     */
    public function getAmount()
    {
        return $this->container['amount'];
    }

    /**
     * Sets amount
     *
     * @param float $amount The budget amount associated with the portfolio. Cannot be `null`.
     *
     * @return $this
     */
    public function setAmount($amount)
    {
        $this->container['amount'] = $amount;

        return $this;
    }

    /**
     * Gets currency_code
     *
     * @return string
     */
    public function getCurrencyCode()
    {
        return $this->container['currency_code'];
    }

    /**
     * Sets currency_code
     *
     * @param string $currency_code The currency used for all monetary values for entities under this profile. Cannot be `null`. |Region|`countryCode`|Country Name|`currencyCode`| |-----|------|------|------| |NA|US|United States|USD| |NA|CA|Canada|CAD| |NA|MX|Mexico|MXN| |NA|BR|Brazil|BRL| |EU|UK|United Kingdom|GBP| |EU|DE|Germany|EUR| |EU|FR|France|EUR| |EU|ES|Spain|EUR| |EU|IT|Italy|EUR| |EU|NL|The Netherlands|EUR| |EU|SE|Sweden|SEK| |EU|PL|Poland|PLN| |EU|AE|United Arab Emirates|AED| |EU|TR|Turkey|TRY| |FE|JP|Japan|JPY| |FE|AU|Australia|AUD| |FE|SG|Singapore|SGD|
     *
     * @return $this
     */
    public function setCurrencyCode($currency_code)
    {
        $allowedValues = $this->getCurrencyCodeAllowableValues();
        if (!is_null($currency_code) && !in_array($currency_code, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value for 'currency_code', must be one of '%s'",
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['currency_code'] = $currency_code;

        return $this;
    }

    /**
     * Gets policy
     *
     * @return string
     */
    public function getPolicy()
    {
        return $this->container['policy'];
    }

    /**
     * Sets policy
     *
     * @param string $policy The budget policy. Set to `dateRange` to specify a budget for a specific period of time. Set to `monthlyRecurring` to specify a budget that is automatically renewed at the beginning of each month. Cannot be `null`.
     *
     * @return $this
     */
    public function setPolicy($policy)
    {
        $allowedValues = $this->getPolicyAllowableValues();
        if (!is_null($policy) && !in_array($policy, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value for 'policy', must be one of '%s'",
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['policy'] = $policy;

        return $this;
    }

    /**
     * Gets start_date
     *
     * @return string
     */
    public function getStartDate()
    {
        return $this->container['start_date'];
    }

    /**
     * Sets start_date
     *
     * @param string $start_date The starting date in `YYYYMMDD` format to which the budget is applied. Required if `policy` is set to `dateRange`. Not specified if `policy` is set to `monthlyRecurring`. Note that the starting date for `monthlyRecurring` is the date when the policy is set.
     *
     * @return $this
     */
    public function setStartDate($start_date)
    {
        $this->container['start_date'] = $start_date;

        return $this;
    }

    /**
     * Gets end_date
     *
     * @return string
     */
    public function getEndDate()
    {
        return $this->container['end_date'];
    }

    /**
     * Sets end_date
     *
     * @param string $end_date The end date after which the budget is no longer applied. Optional if `policy` is set to `dateRange` or `monthlyRecurring`.
     *
     * @return $this
     */
    public function setEndDate($end_date)
    {
        $this->container['end_date'] = $end_date;

        return $this;
    }
    /**
     * Returns true if offset exists. False otherwise.
     *
     * @param integer $offset Offset
     *
     * @return boolean
     */
    #[\ReturnTypeWillChange]
    public function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }

    /**
     * Gets offset.
     *
     * @param integer $offset Offset
     *
     * @return mixed
     */
    #[\ReturnTypeWillChange]
    public function offsetGet($offset)
    {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }

    /**
     * Sets value based on offset.
     *
     * @param integer $offset Offset
     * @param mixed   $value  Value to be set
     *
     * @return void
     */
    #[\ReturnTypeWillChange]
    public function offsetSet($offset, $value)
    {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    /**
     * Unsets offset.
     *
     * @param integer $offset Offset
     *
     * @return void
     */
    #[\ReturnTypeWillChange]
    public function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }

    /**
     * Gets the string presentation of the object
     *
     * @return string
     */
    public function __toString()
    {
        if (defined('JSON_PRETTY_PRINT')) { // use JSON pretty print
            return json_encode(
                ObjectSerializer::sanitizeForSerialization($this),
                JSON_PRETTY_PRINT
            );
        }

        return json_encode(ObjectSerializer::sanitizeForSerialization($this));
    }
}
